package com.company;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class EchoServer {
  public static final int  PORT=9999;       //绑定的端口

  public static void main(String[] args) throws Exception {
    //考虑到性能的优化，最多允许五个用户进行访问
    ExecutorService executorService= Executors.newFixedThreadPool(5);            //声明一个固定大小的线程池
    ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
    serverSocketChannel.configureBlocking(false);                                          //设置非阻塞模式
    serverSocketChannel.bind(new InetSocketAddress(PORT));                                 //服务绑定端口
    //打开一个选择器，随后所有的channel通道都要再次注册
    Selector selector=Selector.open();
    //将当前的serverSocketChannel统一注册到Selector中，接受统一的管理
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    System.out.println("服务器端启动程序，该程序在"+PORT+"端口上监听，等待客户端连接。。");
    //所有的连接处理都需要被selector管理，也就是说，只要有新的用户连接，那么就是通过selector处理
    int keySelect=0;
    while ((keySelect=selector.select())>0){
      Set<SelectionKey> selectionKeys = selector.selectedKeys();
      Iterator<SelectionKey> iterator = selectionKeys.iterator();
      while (iterator.hasNext()) {
        SelectionKey selectionKey =  iterator.next();
        if (selectionKey.isAcceptable()){                    //模式为接收连接模式
          SocketChannel clientChannel=serverSocketChannel.accept(); //等待接收
          if (clientChannel!=null){     //已经有了连接
            executorService.submit(new SocketClientChannelThread(clientChannel));
          }
        }
        iterator.remove();                     //移除此通道
      }
    }
    executorService.shutdown();     //关闭线程池
    serverSocketChannel.close();      //关闭服务器通道
  }

}
